/* ReceivedPackedRegistry.java
 *
 * Copyright 2008 Samolisov Pavel
 * Copyright 2011 Aleksey Konovalov
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 * 
 */
package org.jimm.protocols.icq.packet.received;

import java.io.DataInputStream;
import java.util.HashMap;

import android.util.Log;

import org.jimm.protocols.icq.packet.received.authorization.UINRegistrationFailed__23_1;
import org.jimm.protocols.icq.packet.received.authorization.UINRegistrationSuccess__23_5;
import org.jimm.protocols.icq.packet.received.byddylist.BuddyListRightsReply__3_3;
import org.jimm.protocols.icq.packet.received.byddylist.IncomingUser__3_11;
import org.jimm.protocols.icq.packet.received.byddylist.OffgoingUser__3_12;
import org.jimm.protocols.icq.packet.received.byddylist.RefusedContact__3_10;
import org.jimm.protocols.icq.packet.received.generic.BOSMigration__1_18;
import org.jimm.protocols.icq.packet.received.generic.Motd__1_19;
import org.jimm.protocols.icq.packet.received.generic.OnlineInfoResp__1_15;
import org.jimm.protocols.icq.packet.received.generic.PauseReq__1_11;
import org.jimm.protocols.icq.packet.received.generic.RateReply__1_7;
import org.jimm.protocols.icq.packet.received.generic.ServerFamilies__1_24;
import org.jimm.protocols.icq.packet.received.generic.ServerReady__1_3;
import org.jimm.protocols.icq.packet.received.icbm.ICBMParametersReply__4_5;
import org.jimm.protocols.icq.packet.received.icbm.IncomingMessage__4_7;
import org.jimm.protocols.icq.packet.received.icbm.MessageAck__4_12;
import org.jimm.protocols.icq.packet.received.icbm.MessageAutoReply__4_11;
import org.jimm.protocols.icq.packet.received.icbm.MissedMessage__4_10;
import org.jimm.protocols.icq.packet.received.icbm.ServerICBMError__4_1;
import org.jimm.protocols.icq.packet.received.icbm.TypingNotif__4_20;
import org.jimm.protocols.icq.packet.received.location.LocationRightsReply__2_3;
import org.jimm.protocols.icq.packet.received.meta.MetaError__21_1;
import org.jimm.protocols.icq.packet.received.meta.ServerMetaReply__21_3;
import org.jimm.protocols.icq.packet.received.privacy.BosRightReply__9_3;
import org.jimm.protocols.icq.packet.received.ssi.SsiAuthReply__19_27;
import org.jimm.protocols.icq.packet.received.ssi.SsiAuthRequest__19_25;
import org.jimm.protocols.icq.packet.received.ssi.SsiContactListReply__19_6;
import org.jimm.protocols.icq.packet.received.ssi.SsiFutureAuthGranted__19_20;
import org.jimm.protocols.icq.packet.received.ssi.SsiModifyingAck__19_14;
import org.jimm.protocols.icq.packet.received.usagestats.MinReportInterval__11_2;

/**
 * <p>
 * Created by 25.01.2008
 * Modified by 5.03.2011
 *
 * @author Samolisov Pavel
 * @author Konovalov Aleksey
 */
public class ReceivedPackedRegistry {

	private static final String LOG_TAG = "ICQ:ReceivedPackedRegistry";
	private static final HashMap<Integer, Class<? extends ReceivedPacket>> registry = new HashMap<Integer, Class<? extends ReceivedPacket>>();

	static {
		registry.put(makePair(3, 3), BuddyListRightsReply__3_3.class);
		registry.put(makePair(3, 11), IncomingUser__3_11.class);
		registry.put(makePair(3, 12), OffgoingUser__3_12.class);
		registry.put(makePair(3, 10), RefusedContact__3_10.class);
		registry.put(makePair(1, 18), BOSMigration__1_18.class);
		registry.put(makePair(1, 19), Motd__1_19.class);
		registry.put(makePair(1, 15), OnlineInfoResp__1_15.class);
		registry.put(makePair(1, 11), PauseReq__1_11.class);
		registry.put(makePair(1, 7), RateReply__1_7.class);
		registry.put(makePair(1, 24), ServerFamilies__1_24.class);
		registry.put(makePair(1, 3), ServerReady__1_3.class);
		registry.put(makePair(4, 5), ICBMParametersReply__4_5.class);
		registry.put(makePair(4, 7), IncomingMessage__4_7.class);
		registry.put(makePair(4, 12), MessageAck__4_12.class);
		registry.put(makePair(4, 11), MessageAutoReply__4_11.class);
		registry.put(makePair(4, 10), MissedMessage__4_10.class);
		registry.put(makePair(4, 1), ServerICBMError__4_1.class);
		registry.put(makePair(4, 20), TypingNotif__4_20.class);
		registry.put(makePair(2, 3), LocationRightsReply__2_3.class);
		registry.put(makePair(9, 3), BosRightReply__9_3.class);
		registry.put(makePair(19, 27), SsiAuthReply__19_27.class);
		registry.put(makePair(19, 25), SsiAuthRequest__19_25.class);
		registry.put(makePair(19, 6), SsiContactListReply__19_6.class);
		registry.put(makePair(19, 14), SsiModifyingAck__19_14.class);
		registry.put(makePair(19, 20), SsiFutureAuthGranted__19_20.class);
		registry.put(makePair(11, 2), MinReportInterval__11_2.class);
		registry.put(makePair(21, 1), MetaError__21_1.class);
		registry.put(makePair(21, 3), ServerMetaReply__21_3.class);
		registry.put(makePair(23, 5), UINRegistrationSuccess__23_5.class);
		registry.put(makePair(23, 1), UINRegistrationFailed__23_1.class);
	}

	private static final int makePair(int a, int b) {
		return ((a & 0xFFFF) << 16) | (b & 0xFFFF);
	}

	public static final ReceivedPacket getPacketHandler(int familyId,
			int subtype, DataInputStream data) {
		Class<? extends ReceivedPacket> receivedPacketClass = registry
				.get(makePair(familyId, subtype));
		if (receivedPacketClass == null)
			return null;

		final Class<?>[] constructorParam = new Class<?>[] { data.getClass() };
		ReceivedPacket result = null;
		try {
			result = receivedPacketClass.getConstructor(constructorParam).newInstance(
					new Object[] { data });
		} catch (Exception e) {
			Log.e(LOG_TAG, "getPacketHandler error", e);
		}
		return result;
	}

	private ReceivedPackedRegistry() {
	}
}
